﻿using System;
using System.Collections.Generic;
using Microsoft.DirectX;
using MultiResolutioning.Interfaces;

namespace MultiResolutioning.Structures
{
	/// <summary>
	/// Klasa reprezentuje wierzcholek.
	/// </summary>
	public class Vertex: IComparable<Vertex>, ICollectionable
	{
		public int vertexId;
		public int saveId;
		public Vector3 normal = Vector3.Empty;
		public Vector3 position;
		public float[] additionalProperties;
		public List<Face> faces = new List<Face>();
		public List<Vertex> neighbors = new List<Vertex>();
		public ICostable simplOperation;
		public bool removed = false;
		public object additionalField;

		/// <summary>
		/// Inicjalizuje obiekt.
		/// </summary>
		public Vertex()
		{
			this.position = new Vector3(0, 0, 0);
		}

		/// <summary>
		/// Inicjalizuje obiekt.
		/// </summary>
		/// <param name="x">Wspolrzedna x.</param>
		/// <param name="y">Wspolrzedna y.</param>
		/// <param name="z">Wspolrzedna z.</param>
		public Vertex(float x, float y, float z)
		{
			this.position = new Vector3(x, y, z);
		}

		/// <summary>
		/// Porownuje wierzcholki.
		/// </summary>
		/// <param name="other">The other.</param>
		/// <returns></returns>
		public int CompareTo(Vertex other)
		{
			if (this.simplOperation.Cost < other.simplOperation.Cost)
				return -1;
			if (this.simplOperation.Cost > other.simplOperation.Cost)
				return 1;
			else
				return 0;
		}

		/// <summary>
		/// Tworzy kopie instancji wierzcholka.
		/// </summary>
		/// <returns></returns>
		public Vertex Clone()
		{
			Vertex cloned = new Vertex();
			cloned.vertexId = this.vertexId;
			cloned.saveId = this.saveId;
			cloned.position = new Vector3(this.position.X, this.position.Y, this.position.Z);
			cloned.faces = new List<Face>(this.faces);
			cloned.neighbors = new List<Vertex>(this.neighbors);
			cloned.simplOperation = simplOperation;
			cloned.removed = this.removed;
			cloned.additionalField = this.additionalField;

			return cloned;
		}

		/// <summary>
		/// Oblicza wektor normalny wierzcholka na podstawie trojkatow na nim sie opierajacych.
		/// </summary>
		public void ComputeNormal()
		{
			foreach (Face f in this.faces)
				this.normal += f.normal;

			normal.Normalize();
		}

		/// <summary>
		/// Ustawia lub zwraca swoj indeks w kolekcji sledzacej pozycje elementow.
		/// </summary>
		/// <value>
		/// Indeks elementu w kolekcji.
		/// </value>
		public int InCollectionIndex { get; set; }
	}
}
